package com.ruoyi.business.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.business.domain.TAccountInfo;
import com.ruoyi.business.domain.TAccountLog;
import com.ruoyi.business.enums.AccountInfoExceptionEnum;
import com.ruoyi.business.enums.AccountOpType;
import com.ruoyi.business.mapper.TAccountInfoMapper;
import com.ruoyi.business.service.ITAccountInfoService;
import com.ruoyi.business.service.ITAccountLogService;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MoneyUtil;
import com.ruoyi.common.utils.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 商户账户Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-02-26
 */
@Service
public class TAccountInfoServiceImpl implements ITAccountInfoService 
{
    @Autowired
    private TAccountInfoMapper tAccountInfoMapper;


    @Autowired
    private ITAccountLogService accountLogService;
    /**
     * 查询商户账户
     * 
     * @param id 商户账户主键
     * @return 商户账户
     */
    @Override
    public TAccountInfo selectTAccountInfoById(Long id)
    {
        return tAccountInfoMapper.selectTAccountInfoById(id);
    }

    /**
     * 查询商户账户列表
     * 
     * @param tAccountInfo 商户账户
     * @return 商户账户
     */
    @Override
    @DataScope(userAlias = "t")
    public List<TAccountInfo> selectTAccountInfoList(TAccountInfo tAccountInfo)
    {
        return tAccountInfoMapper.selectTAccountInfoList(tAccountInfo);
    }

    @Override
    public List<TAccountInfo> selectTAccountInfoListByNoAuth(TAccountInfo tAccountInfo) {
        return tAccountInfoMapper.selectTAccountInfoListByNoAuth(tAccountInfo);

    }

    /**
     * 新增商户账户
     * 
     * @param tAccountInfo 商户账户
     * @return 结果
     */
    @Override
    public int insertTAccountInfo(TAccountInfo tAccountInfo)
    {
        tAccountInfo.setCreateTime(DateUtils.getNowDate());
        return tAccountInfoMapper.insertTAccountInfo(tAccountInfo);
    }

    /**
     * 修改商户账户
     * 
     * @param tAccountInfo 商户账户
     * @return 结果
     */
    @Override
    public int updateTAccountInfo(TAccountInfo tAccountInfo)
    {
        tAccountInfo.setUpdateTime(DateUtils.getNowDate());
        return tAccountInfoMapper.updateTAccountInfo(tAccountInfo);
    }

    /**
     * 批量删除商户账户
     * 
     * @param ids 需要删除的商户账户主键
     * @return 结果
     */
    @Override
    public int deleteTAccountInfoByIds(String ids)
    {
        return tAccountInfoMapper.deleteTAccountInfoByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除商户账户信息
     * 
     * @param id 商户账户主键
     * @return 结果
     */
    @Override
    public int deleteTAccountInfoById(Long id)
    {
        return tAccountInfoMapper.deleteTAccountInfoById(id);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    @Override
    public void recharge(TAccountInfo accountInfoParam) {
        TAccountInfo accountInfo = tAccountInfoMapper.selectTAccountInfoById(accountInfoParam.getId());
        long userId = ShiroUtils.getSysUser().getUserId();
        TAccountInfo query = new TAccountInfo();
        query.setUserId(userId);
        TAccountInfo myAccount = tAccountInfoMapper.selectTAccountInfoList(query).get(0);
        boolean isAdmin = ShiroUtils.getSysUser().isAdmin();
        boolean isDataAdmin = ShiroUtils.getSysUser().isDataAdmin(ShiroUtils.getSysUser().getRoles());
        if (accountInfo.getUserId() == userId) {
            throw new ServiceException(AccountInfoExceptionEnum.NOT_PERMISSION.getMessage());
        }
        TAccountLog accountLog = new TAccountLog();
        TAccountLog myAccountLog = new TAccountLog();
        Random random = new Random();
        long bizId = random.nextLong();
        accountLog.setAccountId(accountInfo.getId());
        accountLog.setUserId(accountInfo.getUserId());
        accountLog.setBizId(bizId);
        if(!isAdmin && !isDataAdmin){
            myAccountLog.setAccountId(myAccount.getId());
            myAccountLog.setUserId(myAccount.getUserId());
            myAccountLog.setBizId(bizId);
        }

        if (accountInfoParam.getOperAmount() > 0) {
            if (!isAdmin && !isDataAdmin) {
                if (MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + "") > myAccount.getBalance()) {
                    throw new ServiceException(AccountInfoExceptionEnum.NOT_MY_BALANCE.getMessage());
                }
                accountLog.setOpType(AccountOpType.RECHARGE_PROXY.getVal());
                accountLog.setOpDesc(String.format(AccountOpType.RECHARGE_PROXY.getDesc() + "%d成功新增余额%s元", accountLog.getBizId(),
                        accountInfoParam.getOperAmount()));
            }else{
                accountLog.setOpType(AccountOpType.RECHARGE_PLATFORM.getVal());
                accountLog.setOpDesc(String.format(AccountOpType.RECHARGE_PLATFORM.getDesc() + "%d成功新增余额%s元", accountLog.getBizId(),
                        accountInfoParam.getOperAmount()));
            }

            accountLog.setOpAmount(MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
            accountInfo.setTodayIncome(accountInfo.getTodayIncome() + MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
            accountInfo.setTotalIncome(accountInfo.getTotalIncome() + MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
            if (!isAdmin && !isDataAdmin) {
                myAccountLog.setOpDesc(String.format(AccountOpType.RECHARGE_PROXY.getDesc() + "%d成功扣除余额%s元", myAccountLog.getBizId(),
                        accountInfoParam.getOperAmount()));
                myAccountLog.setOpType(AccountOpType.RECHARGE_PROXY.getVal());
                myAccount.setTodayExpend(myAccount.getTodayExpend() + MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
                myAccount.setTotalExpend(myAccount.getTotalExpend() + MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
                myAccountLog.setOpAmount(MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + "") * -1);

            }

        } else {
            if (!isAdmin && !isDataAdmin) {
                if ((MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + "") + accountInfo.getBalance() < 0)) {
                    throw new ServiceException(AccountInfoExceptionEnum.NOT_MY_BALANCE.getMessage());
                }
            }
            accountLog.setOpType(AccountOpType.REVERSAL_BALANCE.getVal());
            accountLog.setOpDesc(String.format(AccountOpType.REVERSAL_BALANCE.getDesc() + "%d成功扣除余额%s元", accountLog.getBizId(),
                    accountInfoParam.getOperAmount()));
            accountInfo.setTodayExpend(accountInfo.getTodayExpend() - MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
            accountInfo.setTotalExpend(accountInfo.getTotalExpend() - MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
            accountLog.setOpAmount(MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + "") * -1);

            if (!isAdmin && !isDataAdmin) {
                myAccountLog.setOpAmount(MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
                myAccountLog.setOpType(AccountOpType.REVERSAL_BALANCE.getVal());
                myAccountLog.setOpDesc(String.format(AccountOpType.REVERSAL_BALANCE.getDesc() + "%d成功增加余额%s元", myAccountLog.getBizId(),
                        accountInfoParam.getOperAmount()));
                myAccount.setTodayIncome(myAccount.getTodayIncome() - MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));
                myAccount.setTotalIncome(myAccount.getTotalIncome() - MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + ""));

            }
        }
        long balance = accountInfo.getBalance() + MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + "");
        long mybalance = 0L;
        if (!isAdmin && !isDataAdmin) {
            mybalance = myAccount.getBalance() - MoneyUtil.yuanToFen(accountInfoParam.getOperAmount() + "");
        }
        // 操作金额。单位分。正数-收入，负数-支出
        accountLog.setOldAmount(accountInfo.getBalance());
        accountLog.setNewAmount(balance);
        accountInfo.setBalance(balance);
        accountInfo.setLastRecharge(new Date());
        // 流水
        accountLogService.insertTAccountLog(accountLog);
        tAccountInfoMapper.updateTAccountInfo(accountInfo);
        // 流水
        if (!isAdmin && !isDataAdmin) {
            myAccountLog.setOldAmount(myAccount.getBalance());
            myAccountLog.setNewAmount(mybalance);
            myAccount.setBalance(mybalance);
            accountLogService.insertTAccountLog(myAccountLog);
            tAccountInfoMapper.updateTAccountInfo(myAccount);
        }
    }

    @Override
    public TAccountInfo selectTAccountInfoByUserId(Long id) {
        return tAccountInfoMapper.selectTAccountInfoByUserId(id);
    }

    @Override
    public void resetTAccountInfo() {
        tAccountInfoMapper.resetTAccountInfo();

    }

    /**
     * 获取商户账户
     *
     * @author allen
     * @date 2022-06-11 15:52:04
     */
    private TAccountInfo queryAccountInfo(TAccountInfo accountInfoParam) {
        TAccountInfo accountInfo = tAccountInfoMapper.selectTAccountInfoById(accountInfoParam.getId());
        if (ObjectUtil.isNull(accountInfo)) {
            throw new ServiceException(AccountInfoExceptionEnum.NOT_EXIST.getMessage());
        }
        return accountInfo;
    }
}
